"""
GRANT权限管理操作符实现
"""

from typing import Optional, List, Dict, Any, Iterator
import time

from ..executor_base import IteratorExecutor
from ..types import Record, RecordBatch, ExecutionContext
from ..storage_adapter import StorageEngineAdapter


class GrantOperator(IteratorExecutor):
    """GRANT权限授予操作符"""
    
    def __init__(self, executor_id: str, context: ExecutionContext,
                 privileges: str, object_type: str, object_name: str,
                 grantees: str, grant_option: str = None,
                 storage_engine: StorageEngineAdapter = None):
        super().__init__(executor_id, context)
        self.privileges = privileges
        self.object_type = object_type
        self.object_name = object_name
        self.grantees = grantees
        self.grant_option = grant_option
        self.storage_engine = storage_engine
        self.executed = False
        self.success = False
    
    def open(self):
        """打开GRANT操作符"""
        with self.lock:
            if self.is_open:
                return
            
            self.is_open = True
            self.current_iterator = self._create_grant_iterator()
            
            # 更新统计信息
            self.update_stats(io_ops=1)
    
    def _create_grant_iterator(self) -> Iterator[Record]:
        """创建GRANT执行迭代器"""
        try:
            # 执行权限授予操作
            self._execute_grant()
            
            # 返回操作结果
            result_record = {
                'operation': 'GRANT',
                'privileges': self.privileges,
                'object_type': self.object_type,
                'object_name': self.object_name,
                'grantees': self.grantees,
                'status': 'SUCCESS' if self.success else 'FAILED',
                'message': self._get_result_message()
            }
            
            self.update_stats(rows_returned=1)
            yield result_record
            
        except Exception as e:
            # 授权失败
            error_record = {
                'operation': 'GRANT',
                'status': 'ERROR',
                'message': f"GRANT operation failed: {str(e)}"
            }
            
            self.update_stats(rows_returned=1)
            yield error_record
        
        finally:
            self.executed = True
    
    def _execute_grant(self):
        """执行权限授予"""
        # 这里是权限管理的模拟实现
        # 在实际系统中，这里应该调用权限管理系统的API
        
        try:
            # 解析权限列表
            privilege_list = self._parse_privileges(self.privileges)
            
            # 解析被授权者列表
            grantee_list = self._parse_grantees(self.grantees)
            
            # 验证对象是否存在
            if not self._validate_object():
                raise ValueError(f"Object {self.object_type} '{self.object_name}' does not exist")
            
            # 模拟权限授予过程
            for grantee in grantee_list:
                for privilege in privilege_list:
                    self._grant_privilege_to_user(privilege, grantee)
            
            self.success = True
            
        except Exception as e:
            self.success = False
            raise e
    
    def _parse_privileges(self, privileges_str: str) -> List[str]:
        """解析权限字符串"""
        if privileges_str.upper() == "ALL" or privileges_str.upper() == "ALL PRIVILEGES":
            return ["SELECT", "INSERT", "UPDATE", "DELETE", "CREATE", "DROP", "ALTER"]
        else:
            # 分割权限列表
            return [p.strip().upper() for p in privileges_str.split(',')]
    
    def _parse_grantees(self, grantees_str: str) -> List[str]:
        """解析被授权者字符串"""
        grantees = []
        for grantee in grantees_str.split(','):
            grantee = grantee.strip()
            # 移除可能的USER、ROLE前缀
            if grantee.upper().startswith('USER '):
                grantee = grantee[5:]
            elif grantee.upper().startswith('ROLE '):
                grantee = grantee[5:]
            grantees.append(grantee)
        return grantees
    
    def _validate_object(self) -> bool:
        """验证授权对象是否存在"""
        if self.object_type.upper() == "TABLE":
            # 检查表是否存在
            if self.storage_engine:
                try:
                    table_info = self.storage_engine.get_table_info(self.object_name)
                    return table_info is not None
                except:
                    return False
            else:
                # 没有存储引擎，假设表存在
                return True
        elif self.object_type.upper() == "DATABASE":
            # 数据库级权限，假设数据库存在
            return True
        else:
            # 其他对象类型，假设存在
            return True
    
    def _grant_privilege_to_user(self, privilege: str, grantee: str):
        """向用户授予权限"""
        print(f"[GRANT] 开始向用户 '{grantee}' 授予 '{privilege}' 权限在 {self.object_type} '{self.object_name}' 上")
        
        # 检查存储引擎是否可用
        if not self.storage_engine:
            raise ValueError("Storage engine not available for grant operation")
        
        try:
            # 解析用户名和主机（如果grantee包含@符号）
            if '@' in grantee:
                username, host = grantee.split('@', 1)
            else:
                username, host = grantee, '%'
            
            # 根据对象类型确定数据库和表参数
            database = None
            table = None
            
            if self.object_type.upper() == "TABLE":
                # 表级权限：需要当前数据库名和表名
                current_db = getattr(self.storage_engine, 'database_name', None)
                if not current_db:
                    raise ValueError("Current database not set for table-level privilege")
                database = current_db
                table = self.object_name
            elif self.object_type.upper() == "DATABASE":
                # 数据库级权限：只需要数据库名
                database = self.object_name
            else:
                # 全局权限：database和table都为None
                pass
            
            # 调用存储引擎的grant_privilege方法
            success = self.storage_engine.grant_privilege(
                username=username,
                host=host,
                privilege=privilege,
                database=database,
                table=table
            )
            
            if not success:
                raise RuntimeError(f"Grant privilege failed for user '{username}@{host}'")
            
            print(f"[GRANT] 成功向用户 '{username}@{host}' 授予 '{privilege}' 权限")
            if database and table:
                print(f"[GRANT] 权限范围: 表 {database}.{table}")
            elif database:
                print(f"[GRANT] 权限范围: 数据库 {database}")
            else:
                print(f"[GRANT] 权限范围: 全局")
                
        except Exception as e:
            print(f"[GRANT] 权限授予失败: {e}")
            raise e
    
    def _get_result_message(self) -> str:
        """获取结果消息"""
        if self.success:
            privilege_count = len(self._parse_privileges(self.privileges))
            grantee_count = len(self._parse_grantees(self.grantees))
            message = f"Successfully granted {privilege_count} privilege(s) on {self.object_type} '{self.object_name}' to {grantee_count} grantee(s)"
            
            if self.grant_option:
                message += " with GRANT OPTION"
            
            return message
        else:
            return "GRANT operation failed"
    
    def close(self):
        """关闭GRANT操作符"""
        with self.lock:
            if not self.is_open:
                return
            
            self.is_open = False
            self.current_iterator = None
    
    def get_estimated_cost(self) -> float:
        """获取估算成本"""
        # GRANT操作成本较低
        return 0.1
    
    def get_estimated_rows(self) -> int:
        """获取估算行数"""
        # GRANT操作总是返回1行结果
        return 1


class RevokeOperator(IteratorExecutor):
    """REVOKE权限撤销操作符"""
    
    def __init__(self, executor_id: str, context: ExecutionContext,
                 privileges: str, object_type: str, object_name: str,
                 grantees: str, storage_engine: StorageEngineAdapter = None):
        super().__init__(executor_id, context)
        self.privileges = privileges
        self.object_type = object_type
        self.object_name = object_name
        self.grantees = grantees
        self.storage_engine = storage_engine
        self.executed = False
        self.success = False
    
    def open(self):
        """打开REVOKE操作符"""
        with self.lock:
            if self.is_open:
                return
            
            self.is_open = True
            self.current_iterator = self._create_revoke_iterator()
            
            # 更新统计信息
            self.update_stats(io_ops=1)
    
    def _create_revoke_iterator(self) -> Iterator[Record]:
        """创建REVOKE执行迭代器"""
        try:
            # 执行权限撤销操作
            self._execute_revoke()
            
            # 返回操作结果
            result_record = {
                'operation': 'REVOKE',
                'privileges': self.privileges,
                'object_type': self.object_type,
                'object_name': self.object_name,
                'grantees': self.grantees,
                'status': 'SUCCESS' if self.success else 'FAILED',
                'message': self._get_result_message()
            }
            
            self.update_stats(rows_returned=1)
            yield result_record
            
        except Exception as e:
            # 撤销失败
            error_record = {
                'operation': 'REVOKE',
                'status': 'ERROR',
                'message': f"REVOKE operation failed: {str(e)}"
            }
            
            self.update_stats(rows_returned=1)
            yield error_record
        
        finally:
            self.executed = True
    
    def _execute_revoke(self):
        """执行权限撤销"""
        # 权限撤销的模拟实现
        try:
            # 解析权限列表
            privilege_list = self._parse_privileges(self.privileges)
            
            # 解析被撤销者列表
            grantee_list = self._parse_grantees(self.grantees)
            
            # 模拟权限撤销过程
            for grantee in grantee_list:
                for privilege in privilege_list:
                    self._revoke_privilege_from_user(privilege, grantee)
            
            self.success = True
            
        except Exception as e:
            self.success = False
            raise e
    
    def _parse_privileges(self, privileges_str: str) -> List[str]:
        """解析权限字符串"""
        if privileges_str.upper() == "ALL" or privileges_str.upper() == "ALL PRIVILEGES":
            return ["SELECT", "INSERT", "UPDATE", "DELETE", "CREATE", "DROP", "ALTER"]
        else:
            return [p.strip().upper() for p in privileges_str.split(',')]
    
    def _parse_grantees(self, grantees_str: str) -> List[str]:
        """解析被撤销者字符串"""
        grantees = []
        for grantee in grantees_str.split(','):
            grantee = grantee.strip()
            if grantee.upper().startswith('USER '):
                grantee = grantee[5:]
            elif grantee.upper().startswith('ROLE '):
                grantee = grantee[5:]
            grantees.append(grantee)
        return grantees
    
    def _revoke_privilege_from_user(self, privilege: str, grantee: str):
        """从用户撤销权限"""
        print(f"[REVOKE] 开始从用户 '{grantee}' 撤销 '{privilege}' 权限在 {self.object_type} '{self.object_name}' 上")
        
        # 检查存储引擎是否可用
        if not self.storage_engine:
            raise ValueError("Storage engine not available for revoke operation")
        
        try:
            # 解析用户名和主机（如果grantee包含@符号）
            if '@' in grantee:
                username, host = grantee.split('@', 1)
            else:
                username, host = grantee, '%'
            
            # 根据对象类型确定数据库和表参数
            database = None
            table = None
            
            if self.object_type.upper() == "TABLE":
                # 表级权限：需要当前数据库名和表名
                current_db = getattr(self.storage_engine, 'database_name', None)
                if not current_db:
                    raise ValueError("Current database not set for table-level privilege")
                database = current_db
                table = self.object_name
            elif self.object_type.upper() == "DATABASE":
                # 数据库级权限：只需要数据库名
                database = self.object_name
            else:
                # 全局权限：database和table都为None
                pass
            
            # 调用存储引擎的revoke_privilege方法
            success = self.storage_engine.revoke_privilege(
                username=username,
                host=host,
                privilege=privilege,
                database=database,
                table=table
            )
            
            if not success:
                raise RuntimeError(f"Revoke privilege failed for user '{username}@{host}'")
            
            print(f"[REVOKE] 成功从用户 '{username}@{host}' 撤销 '{privilege}' 权限")
            if database and table:
                print(f"[REVOKE] 权限范围: 表 {database}.{table}")
            elif database:
                print(f"[REVOKE] 权限范围: 数据库 {database}")
            else:
                print(f"[REVOKE] 权限范围: 全局")
                
        except Exception as e:
            print(f"[REVOKE] 权限撤销失败: {e}")
            raise e
    
    def _get_result_message(self) -> str:
        """获取结果消息"""
        if self.success:
            privilege_count = len(self._parse_privileges(self.privileges))
            grantee_count = len(self._parse_grantees(self.grantees))
            return f"Successfully revoked {privilege_count} privilege(s) on {self.object_type} '{self.object_name}' from {grantee_count} grantee(s)"
        else:
            return "REVOKE operation failed"
    
    def close(self):
        """关闭REVOKE操作符"""
        with self.lock:
            if not self.is_open:
                return
            
            self.is_open = False
            self.current_iterator = None
    
    def get_estimated_cost(self) -> float:
        """获取估算成本"""
        return 0.1
    
    def get_estimated_rows(self) -> int:
        """获取估算行数"""
        return 1
